/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.das.commonmodel.entity.increment.merger;

import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.cm.CommonDataTypeControlRuleDef;
import com.inspur.edp.cef.designtime.api.entity.GspCommonDataType;
import com.inspur.edp.cef.designtime.api.entity.increment.ModifyEntityIncrement;
import com.inspur.edp.cef.designtime.api.increment.extractor.ExtractUtils;
import com.inspur.edp.cef.designtime.api.increment.extractor.MonkControlRule;
import com.inspur.edp.cef.designtime.api.increment.merger.AbstractIncrementMerger;
import com.inspur.edp.cef.designtime.api.increment.merger.MergeUtils;
import com.inspur.edp.cef.designtime.api.increment.property.BooleanPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.ObjectPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.PropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.StringPropertyIncrement;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.das.commonmodel.controlrule.CmControlRule;
import com.inspur.edp.das.commonmodel.controlruledef.entity.CmControlRuleDef;
import com.inspur.edp.das.commonmodel.entity.GspCommonModel;
import com.inspur.edp.das.commonmodel.entity.VersionControlInfo;
import com.inspur.edp.das.commonmodel.entity.increment.CommonModelIncrement;
import com.inspur.edp.das.commonmodel.entity.object.increment.extract.CommonObjectIncrementExtractor;
import com.inspur.edp.das.commonmodel.entity.object.increment.merger.CommonObjectIncrementMerger;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import lombok.var;

import java.util.HashMap;
import java.util.List;

public class CommonModelMerger extends AbstractIncrementMerger {

    protected boolean includeAll = false;

    public CommonModelMerger(){}

    public CommonModelMerger(boolean includeAll){
        this.includeAll = includeAll;
    }

    public GspCommonModel merge(
            GspCommonModel extendModel,
            GspCommonModel rootModel,
            CommonModelIncrement extendIncrement,
            CommonModelIncrement baseIncrement,
            CmControlRule rule,
            CmControlRuleDef def) {

        //region ChangeProperties
        var propChanges = baseIncrement.getChangeProperties();
        if (propChanges.size() > 0) {
            mergeChangeProps(extendModel, extendIncrement.getChangeProperties(), propChanges, rule, def);
        }
        //endregion

        //MainObject
        mergeMainObject(extendModel,rootModel, extendIncrement.getMainEntityIncrement(), baseIncrement.getMainEntityIncrement(), rule, def);

        //extendInfo
        mergeExtendInfo(extendModel, extendIncrement, baseIncrement, rule, def);

        return extendModel;
    }

    private void mergeChangeProps(
            GspCommonModel extendModel,
            HashMap<String, PropertyIncrement> extendIncrement,
            HashMap<String, PropertyIncrement> baseIncrement,
            CmControlRule rule,
            CmControlRuleDef def) {

        if (baseIncrement.containsKey(CefNames.Name)) {
            String mergedName = MergeUtils.getStringValue(
                    CefNames.Name,
                    (StringPropertyIncrement) baseIncrement.get(CefNames.Name),
                    extendIncrement,
                    rule.getNameControlRule(),
                    def.getNameControlRule());
            extendModel.setName(mergedName);
        }

//        if (baseIncrement.containsKey(CommonModelNames.VersionControlInfo)) {
//            String mergedVersionInfo = MergeUtils.getStringValue(
//                    CommonModelNames.VersionControlElementId,
//                    (StringPropertyIncrement) baseIncrement.get(CommonModelNames.VersionControlElementId),
//                    extendIncrement,
//                    rule);
//            extendModel.getVersionContronInfo().setVersionControlElementId(mergedVersionInfo);
//        }
    }

    private void mergeAllChange(
            GspCommonModel extendModel,
            HashMap<String, PropertyIncrement> extendIncrement,
            HashMap<String, PropertyIncrement> baseIncrement) {
        for (var incrementPair : baseIncrement.entrySet()) {
            String key = incrementPair.getKey();
            PropertyIncrement increment = incrementPair.getValue();
            dealChangeProp(extendModel, extendIncrement, key, increment);
        }
    }

    private void dealChangeProp(GspCommonModel extendModel, HashMap<String, PropertyIncrement> extendIncrement, String key, PropertyIncrement increment) {
        switch (key){
            case CefNames.Name:
                String mergedName = MergeUtils.getStringValue(CefNames.Name, (StringPropertyIncrement)increment, extendIncrement, null,null);
                extendModel.setName(mergedName);
                return;
            case CefNames.Code:
                String mergedCode = MergeUtils.getStringValue(CefNames.Code, (StringPropertyIncrement)increment, null, null,null);
                extendModel.setCode(mergedCode);
                return;
            case CefNames.IsVirtual:
                boolean mergedIsVirtual = MergeUtils.getBooleanValue(CefNames.IsVirtual, (BooleanPropertyIncrement)increment, null, null,null);
                extendModel.setIsVirtual(mergedIsVirtual);
                return;
            case CefNames.I18nResourceInfoPrefix:
                String mergedI18n = MergeUtils.getStringValue(CefNames.I18nResourceInfoPrefix, (StringPropertyIncrement)increment, null, null,null);
                extendModel.setI18nResourceInfoPrefix(mergedI18n);
                return;
            case CefNames.BeLabel:
                List<String> mergedBeLabel = MergeUtils.getObjectValue(CefNames.BeLabel, (ObjectPropertyIncrement)increment, null, null,null);
                extendModel.setBeLabel(mergedBeLabel);
                return;
            case CommonModelNames.EntityType:
                String mergedEntityType = MergeUtils.getStringValue(CommonModelNames.EntityType, (StringPropertyIncrement)increment, null, null,null);
                extendModel.setEntityType(mergedEntityType);
                return;
            case CommonModelNames.GeneratingAssembly:
                String mergedAssembly = MergeUtils.getStringValue(CommonModelNames.GeneratingAssembly, (StringPropertyIncrement)increment, null, null,null);
                extendModel.setDotnetGeneratingAssembly(mergedAssembly);
                return;
            case CommonModelNames.IsUseNamespaceConfig:
                boolean mergedIsUseNamespace = MergeUtils.getBooleanValue(CommonModelNames.IsUseNamespaceConfig, (BooleanPropertyIncrement)increment, null, null,null);
                extendModel.setIsUseNamespaceConfig(mergedIsUseNamespace);
                return;
            case CommonModelNames.VersionControlElementId:
                String mergedVersion = MergeUtils.getStringValue(CommonModelNames.VersionControlElementId, (StringPropertyIncrement)increment, null, null,null);
                if(extendModel.getVersionContronInfo() == null)
                    extendModel.setVersionContronInfo(new VersionControlInfo());
                extendModel.getVersionContronInfo().setVersionControlElementId(mergedVersion);
                return;
        }

        dealExtendChangeProp(extendModel, extendIncrement, key, increment);
    }

    protected void dealExtendChangeProp(GspCommonModel extendModel, HashMap<String, PropertyIncrement> extendIncrement, String key, PropertyIncrement increment){

    }


    private void mergeMainObject(
            GspCommonModel extendModel,
            GspCommonModel rootModel,
            ModifyEntityIncrement extendIncrement,
            ModifyEntityIncrement baseIncrement,
            CmControlRule rule,
            CmControlRuleDef def) {
        if (baseIncrement == null)
            return;
        var objMerger = getCommonObjectIncrementMerger();
        objMerger.merge(extendModel.getMainObject(),rootModel.getMainObject(), extendIncrement, baseIncrement, rule.getMainEntityControlRule(),(CommonDataTypeControlRuleDef)def.getChildControlRules().get(CommonModelNames.MainObject));
    }


    protected CommonObjectIncrementMerger getCommonObjectIncrementMerger(){
        return new CommonObjectIncrementMerger();
    }

    protected void mergeExtendInfo(
            GspCommonModel extendModel,
            CommonModelIncrement extendIncrement,
            CommonModelIncrement baseIncrement,
            CmControlRule rule,
            CmControlRuleDef def){

    }
}
